#include "StdAfx.h"
#include "ReportPreview.h"

#include "../_inc_util/UtilRender.h"
#include "StatusMgr.h"
#include "Resource.h"
//#include "DlgViewerBG.h"


void CReportPreview::GetPrintOutDC(CDC* pDC, RECT* pRc,	PREPORT_ITEM pReportItem, PRINTINFO* pPrintInfo, CDlgViewerBG *pViewerSetup)
{
	// Print Dialog
	CPrintDialog dlg(FALSE);
	

	CUtilRender OperRender;

	BYTE* pRgbData[MAX_CHANNEL];
	BITMAPINFO bmiTarget[MAX_CHANNEL];
	int nMaxChannel;
	//VIEWER_SETTING stViewerSet;
	//stViewerSet = pViewerSetup->GetViewerSet();
	nMaxChannel = 2;//(int)stViewerSet.dwViewerMode;

	int i;
	for (i=0; i<nMaxChannel; i++)
	{
		if (pReportItem->vidStream[i].pStream != NULL)
		{
			pRgbData[i] = new BYTE[pReportItem->vidStream[i].dwWidth*pReportItem->vidStream[i].dwHeight*3];
			
			OperRender.Rgb32ToRgb24(pRgbData[i], pReportItem->vidStream[i].pStream, 
									pReportItem->vidStream[i].dwWidth, pReportItem->vidStream[i].dwHeight);		

			memset(&bmiTarget[i], 0x00, sizeof(BITMAPINFO));
			bmiTarget[i].bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
			bmiTarget[i].bmiHeader.biWidth			= pReportItem->vidStream[i].dwWidth;
			bmiTarget[i].bmiHeader.biHeight		    = pReportItem->vidStream[i].dwHeight;
			bmiTarget[i].bmiHeader.biPlanes		    = 1;
			bmiTarget[i].bmiHeader.biBitCount		= 24;
			bmiTarget[i].bmiHeader.biCompression	= BI_RGB;
			bmiTarget[i].bmiHeader.biSizeImage		= pReportItem->vidStream[i].dwWidth*pReportItem->vidStream[i].dwHeight*3;
			bmiTarget[i].bmiHeader.biXPelsPerMeter	= 0;
			bmiTarget[i].bmiHeader.biYPelsPerMeter	= 0;
			bmiTarget[i].bmiHeader.biClrUsed		= 0;
			bmiTarget[i].bmiHeader.biClrImportant	= 0;
		}
		else
		{
			pRgbData[i] = NULL;
		}
	}	

	// Document Location
	HDC hdcPrinter;
	CDC dcPrinter;
	int nLogPixelsX;
	int nLogPixelsY;
	int nHorzRes;
	int nVertRes;
	if(!dlg.GetDefaults())
	{
		nLogPixelsX = 600;
		nLogPixelsY = 600;
		nHorzRes = 4672;
		nVertRes = 6774;
	}
	else
	{
		hdcPrinter = dlg.GetPrinterDC();
		dcPrinter.Attach(hdcPrinter);
		nLogPixelsX = dcPrinter.GetDeviceCaps(LOGPIXELSX); 
		nLogPixelsY = dcPrinter.GetDeviceCaps(LOGPIXELSY); 
		nHorzRes = dcPrinter.GetDeviceCaps(HORZRES); 
		nVertRes = dcPrinter.GetDeviceCaps(VERTRES); 
	}
	int nScaleX		= (nHorzRes - nLogPixelsX * 2) / 4;
	int nScaleY		= (nVertRes - nLogPixelsY * 2) / 3;
	int nPrintWidth, nPrintHeight, nPrintLeft, nPrintTop;

	nPrintWidth		= (nHorzRes - nLogPixelsX);
	nPrintHeight	= (nVertRes - nLogPixelsY);
	nPrintLeft		= (nHorzRes - nPrintWidth) / 2;
	nPrintTop		= (nVertRes - nPrintHeight) / 2;

	int nW = pRc->right - pRc->left;
	int nH = pRc->bottom - pRc->top;

	int nLine = 40;
	int nFontHeight = 18;

	int nPaperWidth, nPaperHeight;
	if(nHorzRes < nVertRes)
	{
		nPaperHeight = nH - 20;
		nPaperWidth = (int)(((float)nHorzRes / (float)nVertRes) * (float)nPaperHeight);
	}
	else
	{
		nPaperWidth = nW - 20;
		nPaperHeight = (int)(((float)nVertRes / (float)nHorzRes) * (float)nPaperWidth);
	}

	// DRAW BACKGROUND
	pDC->SetROP2(R2_COPYPEN);
	pDC->SelectObject(GetStockObject(GRAY_BRUSH));
	pDC->Rectangle(pRc);

	// DRAW PAPER
	RECT rcPaper;
	rcPaper.top		= ((nH - nPaperHeight) / 2) + 2 + pRc->top;
	rcPaper.left	= ((nW - nPaperWidth) / 2) + 2 + pRc->left;
	rcPaper.bottom	= (rcPaper.top + nPaperHeight) + 2;
	rcPaper.right	= (rcPaper.left + nPaperWidth) + 2;
	pDC->SetROP2(R2_BLACK);
	pDC->Rectangle(&rcPaper);
	rcPaper.top		= ((nH - nPaperHeight) / 2) + pRc->top;
	rcPaper.left	= ((nW - nPaperWidth)/ 2) + pRc->left;
	rcPaper.bottom	= rcPaper.top + nPaperHeight;
	rcPaper.right	= rcPaper.left + nPaperWidth;
	pDC->SetROP2(R2_WHITE);
	pDC->Rectangle(&rcPaper);

	float nRatio = (float)nHorzRes / (float)nPaperWidth;
	nPrintTop	= (int)((float)nPrintTop / nRatio);
	nPrintLeft	= (int)((float)nPrintLeft / nRatio);
	nPrintWidth	= (int)((float)nPrintWidth / nRatio);
	nPrintHeight= (int)((float)nPrintHeight / nRatio);
	nLogPixelsY = (int)((float)nLogPixelsY / nRatio);

	pDC->SetMapMode(MM_ANISOTROPIC);

	nPrintTop	+= rcPaper.top;
	nPrintLeft	+= rcPaper.left;

	int nGridX = nPrintWidth / 17;
	int nGridY = nPrintHeight / nLine;
	nFontHeight = nPrintHeight / 26;
	int nGap = nFontHeight/3;

	// TEXT ----------------------------------------------------------------------------
	CFont Font, *pFontOld;
	Font.CreateFont(nFontHeight, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0,
		DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, DEFAULT_FONT);
	pFontOld = pDC->SelectObject(&Font);
	//1. title
	pDC->TextOut(nPrintLeft, nPrintTop, pPrintInfo->tzTitle, _tcslen(pPrintInfo->tzTitle));
	pDC->SelectObject(pFontOld);
	Font.DeleteObject();

	CFont Font1, *pFontOld1;
	Font1.CreateFont(nFontHeight / 2, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
		DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, DEFAULT_FONT);
	pFontOld1 = pDC->SelectObject(&Font1);

	//2. date
	pDC->TextOut(nPrintLeft + (1 * nGridX), nPrintTop + ((nLine-12) * nGridY)-nGap*3,	   pPrintInfo->tzLine1,  _tcslen(pPrintInfo->tzLine1));
	pDC->TextOut(nPrintLeft + (1 * nGridX) + 8, nPrintTop + ((nLine-11) * nGridY)-nGap*3, pPrintInfo->tzLine1C, _tcslen(pPrintInfo->tzLine1C));

	//3. GPS
	pDC->TextOut(nPrintLeft + (1 * nGridX), nPrintTop + ((nLine-10) * nGridY)-nGap*2,	   pPrintInfo->tzLine2,  _tcslen(pPrintInfo->tzLine2));
	pDC->TextOut(nPrintLeft + (1 * nGridX) + 8, nPrintTop + ((nLine-9) * nGridY)-nGap*2, pPrintInfo->tzLine2C1, _tcslen(pPrintInfo->tzLine2C1));
	pDC->TextOut(nPrintLeft + (4 * nGridX) + 13, nPrintTop + ((nLine-9) * nGridY)-nGap*2, pPrintInfo->tzLine2C2, _tcslen(pPrintInfo->tzLine2C2));
	pDC->TextOut(nPrintLeft + (8 * nGridX) + 13, nPrintTop + ((nLine-9) * nGridY)-nGap*2, pPrintInfo->tzLine2C3, _tcslen(pPrintInfo->tzLine2C3));

	//4. G-Sensor
	pDC->TextOut(nPrintLeft + (1 * nGridX), nPrintTop + ((nLine-8) * nGridY)-nGap,	   pPrintInfo->tzLine3,  _tcslen(pPrintInfo->tzLine3));
	pDC->TextOut(nPrintLeft + (1 * nGridX) + 8, nPrintTop + ((nLine-7) * nGridY)-nGap, pPrintInfo->tzLine3C, _tcslen(pPrintInfo->tzLine3C));

	//5. 
	pDC->TextOut(nPrintLeft + (1 * nGridX), nPrintTop + ((nLine-6) * nGridY),		   pPrintInfo->tzLine4, _tcslen(pPrintInfo->tzLine4));
	pDC->TextOut(nPrintLeft + (1 * nGridX) + 8, nPrintTop + ((nLine-5) * nGridY),	   pPrintInfo->tzMemo1, _tcslen(pPrintInfo->tzMemo1));
	pDC->TextOut(nPrintLeft + (1 * nGridX) + 8, nPrintTop + ((nLine-4) * nGridY),	   pPrintInfo->tzMemo2, _tcslen(pPrintInfo->tzMemo2));
	pDC->TextOut(nPrintLeft + (1 * nGridX) + 8, nPrintTop + ((nLine-3) * nGridY),	   pPrintInfo->tzMemo3, _tcslen(pPrintInfo->tzMemo3));
	pDC->TextOut(nPrintLeft + (1 * nGridX) + 8, nPrintTop + ((nLine-2) * nGridY),	   pPrintInfo->tzMemo4, _tcslen(pPrintInfo->tzMemo4));
	pDC->TextOut(nPrintLeft + (1 * nGridX) + 8, nPrintTop + ((nLine-1) * nGridY),	   pPrintInfo->tzMemo5, _tcslen(pPrintInfo->tzMemo5));

	pDC->TextOut(nPrintLeft + (nGridX * 7), nPrintTop + ((nLine-0) * nGridY),	   pPrintInfo->tzBottom, _tcslen(pPrintInfo->tzBottom));
	pDC->SelectObject(pFontOld1);
	Font1.DeleteObject(); 

	// LINE ----------------------------------------------------------------------------
	pDC->SetROP2(R2_BLACK);
	pDC->MoveTo(nPrintLeft, nPrintTop + nFontHeight);
	pDC->LineTo(nPrintLeft + (17 * nGridX), nPrintTop + nFontHeight);


	pDC->MoveTo(nPrintLeft, nPrintTop + ((nLine-0) * nGridY));
	pDC->LineTo(nPrintLeft + (17 * nGridX), nPrintTop + ((nLine-0) * nGridY));

	// IMAGE ----------------------------------------------------------------------------
	SetStretchBltMode(pDC->m_hDC, COLORONCOLOR);

	int nX[MAX_CHANNEL], nY[MAX_CHANNEL];
	int nCount = 0;

	nX[0] = nGridX*16;
	nY[0] = nX[0]*9/16;

	nX[1] = nGridX*8;
	nY[1] = nX[1]*2/3;

	StretchDIBits(pDC->GetSafeHdc(),
		nPrintLeft + (1 * nGridX/2), nPrintTop + (2 * nGridY), nX[nCount], nY[nCount],
		0, 0, pReportItem->vidStream[0].dwWidth, pReportItem->vidStream[nCount].dwHeight,
		pRgbData[nCount],
		&bmiTarget[nCount],
		DIB_RGB_COLORS,
		SRCCOPY);

	nCount++;
	if (nCount<nMaxChannel)
	{
		if (pReportItem->vidStream[nCount].pStream != NULL)
		{
			StretchDIBits(pDC->GetSafeHdc(),
				nPrintLeft + (1 * nGridX/2), nPrintTop + nY[nCount-1]+(5*nGridY/2), nX[nCount], nY[nCount],
				0, 0, pReportItem->vidStream[nCount].dwWidth, pReportItem->vidStream[nCount].dwHeight,
				pRgbData[nCount],
				&bmiTarget[nCount],
				DIB_RGB_COLORS,
				SRCCOPY);
		}
	}

	for (i=0; i<nMaxChannel; i++)
	{
		if (pRgbData[i])
			delete pRgbData[i];
	}
}

void CReportPreview::PrintOut(PREPORT_ITEM pReportItem, PRINTINFO*	pPrintInfo, CDlgViewerBG *pViewerSetup)
{	
	// Print Dialog
	CPrintDialog dlg(FALSE);
	if (dlg.DoModal() != IDOK) return;

	CUtilRender OperRender;

	BYTE* pRgbData[4];
	BITMAPINFO bmiTarget[4];
	//VIEWER_SETTING stViewerSet;
	int nChannel;
	//stViewerSet = pViewerSetup->GetViewerSet();
	nChannel = 2;//(int)stViewerSet.dwViewerMode;

	int i;
	for (i=0; i<nChannel; i++)
	{
		// Convert RAW Data to Bitmap
		pRgbData[i] = new BYTE[pReportItem->vidStream[i].dwWidth*pReportItem->vidStream[i].dwHeight*3];

		OperRender.Rgb32ToRgb24(pRgbData[i], pReportItem->vidStream[i].pStream, 
								pReportItem->vidStream[i].dwWidth, pReportItem->vidStream[i].dwHeight);		

		memset(&bmiTarget[i], 0x00, sizeof(BITMAPINFO));
		bmiTarget[i].bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
		bmiTarget[i].bmiHeader.biWidth			= pReportItem->vidStream[i].dwWidth;
		bmiTarget[i].bmiHeader.biHeight		    = pReportItem->vidStream[i].dwHeight;
		bmiTarget[i].bmiHeader.biPlanes		    = 1;
		bmiTarget[i].bmiHeader.biBitCount		= 24;
		bmiTarget[i].bmiHeader.biCompression	= BI_RGB;
		bmiTarget[i].bmiHeader.biSizeImage		= pReportItem->vidStream[i].dwWidth*pReportItem->vidStream[i].dwHeight*3;
		bmiTarget[i].bmiHeader.biXPelsPerMeter	= 0;
		bmiTarget[i].bmiHeader.biYPelsPerMeter	= 0;
		bmiTarget[i].bmiHeader.biClrUsed		= 0;
		bmiTarget[i].bmiHeader.biClrImportant	= 0;
	}

	// Document Location
	HDC hdcPrinter = dlg.GetPrinterDC();
	CDC dcPrinter;
	dcPrinter.Attach(hdcPrinter);
	int nLogPixelsX	= dcPrinter.GetDeviceCaps(LOGPIXELSX);		// pixel per inch
	int nLogPixelsY = dcPrinter.GetDeviceCaps(LOGPIXELSY);		// pixel per inch
	int nHorzRes	= dcPrinter.GetDeviceCaps(HORZRES);			// millimeters		
	int nVertRes	= dcPrinter.GetDeviceCaps(VERTRES);			// millimeters
	int nScaleX		= (nHorzRes - nLogPixelsX * 2) / 4;
	int nScaleY		= (nVertRes - nLogPixelsY * 2) / 3;
	int nPrintWidth, nPrintHeight, nPrintLeft, nPrintTop;

	nPrintWidth		= (nHorzRes - nLogPixelsX);
	nPrintHeight	= (nVertRes - nLogPixelsY);
	nPrintLeft		= (nHorzRes - nPrintWidth) / 2;
	nPrintTop		= (nVertRes - nPrintHeight) / 2;

	DOCINFO docinfo;
	memset(&docinfo, 0, sizeof(DOCINFO));
	docinfo.cbSize = sizeof(docinfo);
	docinfo.lpszDocName = _T("Dvr Print");

	// Print
	if (dcPrinter.StartDoc(&docinfo) >= 0)
	{
		if (dcPrinter.StartPage() >= 0)
		{
			int nLine = 40;
			int nGridX = nPrintWidth / 17;
			int nGridY = nPrintHeight / nLine;
			int nFontHeight = nPrintHeight / 26;
			int nGap = nFontHeight/3;

			// TEXT ----------------------------------------------------------------------------
			CFont Font, *pFontOld;
			Font.CreateFont(nFontHeight, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0,
				DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, DEFAULT_FONT);
			pFontOld = dcPrinter.SelectObject(&Font);
			dcPrinter.TextOut(nPrintLeft, nPrintTop, pPrintInfo->tzTitle, _tcslen(pPrintInfo->tzTitle));
			dcPrinter.SelectObject(pFontOld);
			Font.DeleteObject();

			CFont Font1, *pFontOld1;
			Font1.CreateFont(nFontHeight / 2, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
				DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, DEFAULT_FONT);
			pFontOld1 = dcPrinter.SelectObject(&Font1);

			dcPrinter.TextOut(nPrintLeft + (1 * nGridX), nPrintTop + ((nLine-12) * nGridY)-nGap*3,	   pPrintInfo->tzLine1,  _tcslen(pPrintInfo->tzLine1));
			dcPrinter.TextOut(nPrintLeft + (2 * nGridX), nPrintTop + ((nLine-11) * nGridY)-nGap*3, pPrintInfo->tzLine1C, _tcslen(pPrintInfo->tzLine1C));

			dcPrinter.TextOut(nPrintLeft + (1 * nGridX), nPrintTop + ((nLine-10) * nGridY)-nGap*2,	   pPrintInfo->tzLine2,  _tcslen(pPrintInfo->tzLine2));
			dcPrinter.TextOut(nPrintLeft + (2 * nGridX), nPrintTop + ((nLine-9) * nGridY)-nGap*2, pPrintInfo->tzLine2C1, _tcslen(pPrintInfo->tzLine2C1));
			dcPrinter.TextOut(nPrintLeft + (6 * nGridX), nPrintTop + ((nLine-9) * nGridY)-nGap*2, pPrintInfo->tzLine2C2, _tcslen(pPrintInfo->tzLine2C2));
			dcPrinter.TextOut(nPrintLeft + (10 * nGridX), nPrintTop + ((nLine-9) * nGridY)-nGap*2, pPrintInfo->tzLine2C3, _tcslen(pPrintInfo->tzLine2C3));

			dcPrinter.TextOut(nPrintLeft + (1 * nGridX), nPrintTop + ((nLine-8) * nGridY)-nGap,	   pPrintInfo->tzLine3,  _tcslen(pPrintInfo->tzLine3));
			dcPrinter.TextOut(nPrintLeft + (2 * nGridX) + 8, nPrintTop + ((nLine-7) * nGridY)-nGap, pPrintInfo->tzLine3C, _tcslen(pPrintInfo->tzLine3C));

			dcPrinter.TextOut(nPrintLeft + (1 * nGridX), nPrintTop + ((nLine-6) * nGridY),		   pPrintInfo->tzLine4, _tcslen(pPrintInfo->tzLine4));
			dcPrinter.TextOut(nPrintLeft + (2 * nGridX), nPrintTop + ((nLine-5) * nGridY),	   pPrintInfo->tzMemo1, _tcslen(pPrintInfo->tzMemo1));
			dcPrinter.TextOut(nPrintLeft + (2 * nGridX), nPrintTop + ((nLine-4) * nGridY),	   pPrintInfo->tzMemo2, _tcslen(pPrintInfo->tzMemo2));
			dcPrinter.TextOut(nPrintLeft + (2 * nGridX), nPrintTop + ((nLine-3) * nGridY),	   pPrintInfo->tzMemo3, _tcslen(pPrintInfo->tzMemo3));
			dcPrinter.TextOut(nPrintLeft + (2 * nGridX), nPrintTop + ((nLine-2) * nGridY),	   pPrintInfo->tzMemo4, _tcslen(pPrintInfo->tzMemo4));
			dcPrinter.TextOut(nPrintLeft + (2 * nGridX), nPrintTop + ((nLine-1) * nGridY),	   pPrintInfo->tzMemo5, _tcslen(pPrintInfo->tzMemo5));


			dcPrinter.TextOut(nPrintLeft + (nGridX * 7), nPrintTop + ((nLine-0) * nGridY), pPrintInfo->tzBottom, _tcslen(pPrintInfo->tzBottom));
			dcPrinter.SelectObject(pFontOld1);
			Font1.DeleteObject(); 

			// LINE ----------------------------------------------------------------------------
			CPen Pen, *pPenOld;
			Pen.CreatePen(PS_SOLID, 5, RGB(0, 0, 0));
			pPenOld = dcPrinter.SelectObject(&Pen);
			dcPrinter.MoveTo(nPrintLeft, nPrintTop + nFontHeight);
			dcPrinter.LineTo(nPrintLeft + (17 * nGridX), nPrintTop + nFontHeight);

			dcPrinter.MoveTo(nPrintLeft, nPrintTop + ((nLine-0) * nGridY));
			dcPrinter.LineTo(nPrintLeft + (17 * nGridX), nPrintTop + ((nLine-0) * nGridY));
			dcPrinter.SelectObject(pPenOld);

			// IMAGE ----------------------------------------------------------------------------
			int nX[MAX_CHANNEL], nY[MAX_CHANNEL];
			int nCount = 0;

			nX[0] = nGridX*16;
			nY[0] = nX[0]*9/16;

			nX[1] = nGridX*8;
			nY[1] = nX[1]*2/3;

			StretchDIBits(dcPrinter.GetSafeHdc(),
				nPrintLeft + (1 * nGridX/2), nPrintTop + (2 * nGridY), nX[nCount], nY[nCount],
				0, 0, pReportItem->vidStream[nCount].dwWidth, pReportItem->vidStream[nCount].dwHeight,
				pRgbData[nCount],
				&bmiTarget[nCount],
				DIB_RGB_COLORS,
				SRCCOPY);

			nCount++;
			if (nCount<nChannel)
			{
				StretchDIBits(dcPrinter.GetSafeHdc(),
					nPrintLeft + (1 * nGridX/2), nPrintTop + (5 * nGridY/2) + nY[nCount-1], nX[nCount], nY[nCount],
					0, 0, pReportItem->vidStream[nCount].dwWidth, pReportItem->vidStream[nCount].dwHeight,
					pRgbData[nCount],
					&bmiTarget[nCount],
					DIB_RGB_COLORS,
					SRCCOPY);
			}

			dcPrinter.EndPage();
		}
		else
		{
			dcPrinter.AbortDoc();
		}
		dcPrinter.EndDoc();
	}	

	for (i=0; i<nChannel; i++)
		delete [] pRgbData[i];
}
